Skip to content

Azure mvp deploy - #16

Merged
baasith6 merged 5 commits into
mainfrom
azure-mvp-deploy
Jul 29, 2026
Merged

Azure mvp deploy#16
baasith6 merged 5 commits into
mainfrom
azure-mvp-deploy

Conversation

@baasith6

@baasith6 baasith6 commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Live Snapshot links now appear consistently for configured cameras and open the correct snapshot URL.
    • Installer builds can use explicitly selected Python and Inno Setup tool locations.
  • Improvements

    • Cloud detection now applies consistent default prompt mappings and handles temporary Redis timeouts more reliably.
    • Deployment configuration supports optional prompt overrides and improved backend connectivity settings.
    • Installer validation provides clearer guidance for secure and local backend URLs.
  • Documentation

    • Added deployment guidance for verifying detection prompts, troubleshooting Redis connectivity, and configuring build tools.

baasith6 and others added 5 commits July 29, 2026 15:53
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…roduction.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Jul 29, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The pull request standardizes YOLOE prompt defaults and overrides, improves Redis timeout handling, adds configurable Windows installer tool paths, updates Jenkins deployment wiring and backend configuration, and changes the camera Live Snapshot link binding.

Changes

YOLOE prompt handling

Layer / File(s) Summary
Runtime and evaluation prompt selection
cloud-ai/app/main.py, cloud-ai/eval/run_jacket_test.py
Runtime and jacket evaluation now use shared DEFAULT_YOLOE_PROMPTS; startup logs active prompts and Redis timeouts are handled during polling.
Prompt override configuration and verification
.env.example, infra/mvp/.env.production.example, docs/AZURE_MVP_DEPLOY.md
Documents prompt-to-cue override syntax, built-in defaults, production mappings, evaluation refresh steps, and deployment troubleshooting.

Windows deployment and installer toolchain

Layer / File(s) Summary
Installer tool resolution and execution
connector/installer/build.ps1
Adds configurable Python and ISCC paths, broader executable discovery, and resolved-Python execution for pip and PyInstaller.
Deployment argument forwarding
scripts/build-installer.ps1, scripts/deploy-vm.ps1, connector/app/baked_config.py
Forwards optional tool paths through installer scripts and updates the baked backend URL.
Jenkins tool configuration and deployment commands
Jenkinsfile, docs/JENKINS_DEPLOY.md
Centralizes Windows tool paths, uses configured Python for tests, passes deployment paths, and updates Jenkins setup guidance.

Camera snapshot UI

Layer / File(s) Summary
Live Snapshot link binding
dashboard/src/app/pages/setup/setup.component.ts
Shows the snapshot link when a camera ID exists and uses liveSnapshotUrl for its target.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the Azure MVP deployment-focused changeset, though it is broad and omits the specific scripts and docs updated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch azure-mvp-deploy

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@baasith6
baasith6 merged commit 611357b into main Jul 29, 2026
2 of 4 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cloud-ai/app/main.py`:
- Around line 67-70: Normalize YOLOE prompt configuration in the detector
initialization flow so configured entries merge over DEFAULT_YOLOE_PROMPTS
before building and logging the detector, preserving all unspecified defaults.
Update .env.example lines 79-82 and infra/mvp/.env.production.example lines
61-64 to show or require complete-map semantics, and update
docs/AZURE_MVP_DEPLOY.md line 166 to document the merged behavior.
- Around line 56-62: Update the Redis client construction in
cloud-ai/app/main.py lines 56-62 to use a finite socket_timeout and preserve
explicit timeout recovery with reconnect/retry handling. Update
docs/AZURE_MVP_DEPLOY.md line 165 to describe the finite-timeout and reconnect
strategy instead of recommending Redis socket_timeout=None.
- Around line 108-110: Restrict the redis.TimeoutError handling in the worker
loop to the BRPOP call only, so timeouts from p.lpush after processing a
dequeued job are not swallowed by the same continue path. Preserve the existing
idle-timeout behavior for BRPOP while ensuring post-processing failures retain
the current job for the established retry or dead-letter flow.

In `@connector/installer/build.ps1`:
- Around line 40-43: Update the candidate list in the Inno Setup discovery logic
to include only ISCC.exe and remove the Compil32.exe path from the candidates
added for each user. Preserve the existing Join-Path and synchronous compiler
selection flow.
- Around line 112-118: Update the dependency installation step before the
PyInstaller invocation to check $LASTEXITCODE immediately after the pip command
and stop with a nonzero failure when installation fails. Keep the existing
PyInstaller flow unchanged for successful dependency installation.

In `@Jenkinsfile`:
- Around line 15-16: Move the profile-specific ONEVO_PYTHON and ONEVO_ISCC
assignments out of Jenkinsfile and rely on node-level Jenkins environment
configuration. In docs/JENKINS_DEPLOY.md lines 15-16, instruct operators to
configure both variables for the Jenkins agent/service account rather than
editing Jenkinsfile; in line 94, include Python-path troubleshooting alongside
ISCC troubleshooting.

In `@scripts/deploy-vm.ps1`:
- Around line 86-89: Update scripts/deploy-vm.ps1 lines 86-89 so the installer
arguments do not always set AllowHttp to true; expose HTTP as an explicit opt-in
while defaulting BackendUrl to HTTPS. Update connector/app/baked_config.py line
2 to remove the public plaintext fallback and bake the HTTPS endpoint during
installer builds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 67839896-418e-4e60-b809-bee63abf9ea1

📥 Commits

Reviewing files that changed from the base of the PR and between 275db81 and 7ee7858.

📒 Files selected for processing (12)
  • .env.example
  • Jenkinsfile
  • cloud-ai/app/main.py
  • cloud-ai/eval/run_jacket_test.py
  • connector/app/baked_config.py
  • connector/installer/build.ps1
  • dashboard/src/app/pages/setup/setup.component.ts
  • docs/AZURE_MVP_DEPLOY.md
  • docs/JENKINS_DEPLOY.md
  • infra/mvp/.env.production.example
  • scripts/build-installer.ps1
  • scripts/deploy-vm.ps1
💤 Files with no reviewable changes (1)
  • dashboard/src/app/pages/setup/setup.component.ts

Comment thread cloud-ai/app/main.py
Comment on lines +56 to +62
r = redis.Redis(
host=host,
port=int(port or 6379),
decode_responses=True,
socket_timeout=None,
socket_connect_timeout=5,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
git ls-files | sed -n '1,120p'

echo
echo "cloud-ai/app/main.py outline:"
ast-grep outline cloud-ai/app/main.py || true

echo
echo "cloud-ai/app/main.py relevant lines:"
cat -n cloud-ai/app/main.py | sed -n '1,130p'

echo
echo "docs AZURE_MVP_DEPLOY relevant lines:"
cat -n docs/AZURE_MVP_DEPLOY.md | sed -n '140,180p'

echo
echo "Search Redis socket_timeout and BRPOP:"
rg -n "socket_timeout|BRPOP|decode_responses|redis\.Redis|Timeout reading from socket|worker" cloud-ai app docs .env.example infra -S || true

Repository: baasith6/camera-phase-1

Length of output: 13886


🌐 Web query:

python-redis socket_timeout None blocking command socket_timeout None BRPOP command documentation

💡 Result:

In redis-py, the interaction between the client's socket_timeout and blocking commands like BRPOP has evolved significantly to resolve historical issues where socket-level timeouts would prematurely terminate blocking operations [1][2][3]. 1. Understanding the Timeouts - socket_timeout: This is a client-level configuration that sets a timeout for all low-level socket read/write operations [4][5]. If set to None (the default), the client waits indefinitely for a response from the Redis server [4]. - BRPOP timeout: This is an application-level parameter sent to the Redis server, which determines how long the server should wait for an element to become available in the specified list(s) [6]. A timeout of 0 instructs the server to block indefinitely [6]. 2. Historical Behavior and Issues Previously, if a user set a socket_timeout that was shorter than the BRPOP command's timeout, the client would raise a redis.exceptions.TimeoutError when the socket read exceeded the socket_timeout, even if the Redis server was still waiting for data [1][7]. Users often had to manually work around this by either using a separate Redis client instance without a socket_timeout for blocking operations or by setting the socket_timeout to be longer than the intended blocking duration [7][8]. 3. Current Behavior Recent updates to redis-py have addressed this by introducing logic to identify blocking commands [2][3]. When a blocking command (e.g., BRPOP, BLPOP, BZMPOP) is executed, the client now effectively bypasses or manages the socket_timeout for that specific operation [2][3]. Specifically, the client passes an internal indicator to the connection's read response method, which allows the socket to wait for the duration specified by the server (or indefinitely if the command timeout is 0) without being prematurely cut off by the client's global socket_timeout [2][3]. This ensures that the Redis server maintains control over the blocking duration, as intended [2]. Best Practice While the library now handles this automatically, it is still strongly recommended to set a non-None socket_timeout for production clients to prevent applications from hanging indefinitely in the event of network partitions or dead connections [4]. If your application requires robust blocking behavior, ensure you are using a current version of redis-py to take advantage of these improvements [2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "redis dependency declarations:"
rg -n "redis\s*[:=][<>=~^>]*|redis" cloud-ai/requirements*.txt pyproject.toml poetry.lock Pipfile.lock cloud-ai/Dockerfile -S || true

echo
echo "redis-py changelog/docs availability in repo:"
fd -i 'redis|requirements|pyproject|poetry.lock|lock|Dockerfile|rfdetr|pip' cloud-ai -t f -x sh -c 'echo "--- $1"; sed -n "1,160p" "$1"' sh {}

Repository: baasith6/camera-phase-1

Length of output: 1463


Keep Redis reads bounded and align the troubleshooting guidance.

socket_timeout=None allows stalled Redis reads to block indefinitely, while BRPOP still only controls Redis server-side waiting. Use a finite client socket timeout plus reconnect/retry handling, and update the troubleshooting doc so it no longer presents socket_timeout=None as the fix.

  • cloud-ai/app/main.py#L56-L62: replace the unbounded read timeout with a finite timeout and retain explicit timeout recovery.
  • docs/AZURE_MVP_DEPLOY.md#L165-L165: document the finite-timeout/reconnect strategy instead of Redis socket_timeout=None.
📍 Affects 2 files
  • cloud-ai/app/main.py#L56-L62 (this comment)
  • docs/AZURE_MVP_DEPLOY.md#L165-L165
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cloud-ai/app/main.py` around lines 56 - 62, Update the Redis client
construction in cloud-ai/app/main.py lines 56-62 to use a finite socket_timeout
and preserve explicit timeout recovery with reconnect/retry handling. Update
docs/AZURE_MVP_DEPLOY.md line 165 to describe the finite-timeout and reconnect
strategy instead of recommending Redis socket_timeout=None.

Comment thread cloud-ai/app/main.py
Comment on lines 67 to +70
detector = build_detector(cfg.model_backend, cfg.model, cfg.device, cfg.yoloe_prompts)
active_prompts = cfg.yoloe_prompts or DEFAULT_YOLOE_PROMPTS
print(
f"[cloud-ai] YOLOE prompts ({len(active_prompts)}): {', '.join(active_prompts.keys())}",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Align prompt override semantics across runtime and deployment documentation.

A non-empty CLOUD_AI_YOLOE_PROMPTS mapping currently replaces the entire built-in prompt map, while the examples imply partial overrides. This can silently reduce detection coverage from 12 prompts to only the entries supplied.

  • cloud-ai/app/main.py#L67-L70: merge configured entries over DEFAULT_YOLOE_PROMPTS before building and logging the detector, or validate a complete map.
  • .env.example#L79-L82: remove the partial three-entry example or explicitly require all built-in prompts.
  • infra/mvp/.env.production.example#L61-L64: apply the same complete-map wording and example correction.
  • docs/AZURE_MVP_DEPLOY.md#L166-L166: explain that current values replace defaults, or document the merged behavior after fixing runtime normalization.
📍 Affects 4 files
  • cloud-ai/app/main.py#L67-L70 (this comment)
  • .env.example#L79-L82
  • infra/mvp/.env.production.example#L61-L64
  • docs/AZURE_MVP_DEPLOY.md#L166-L166
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cloud-ai/app/main.py` around lines 67 - 70, Normalize YOLOE prompt
configuration in the detector initialization flow so configured entries merge
over DEFAULT_YOLOE_PROMPTS before building and logging the detector, preserving
all unspecified defaults. Update .env.example lines 79-82 and
infra/mvp/.env.production.example lines 61-64 to show or require complete-map
semantics, and update docs/AZURE_MVP_DEPLOY.md line 166 to document the merged
behavior.

Comment thread cloud-ai/app/main.py
Comment on lines +108 to +110
except redis.TimeoutError:
# BRPOP idle timeout with socket_timeout=None should return None; ignore stray timeouts.
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== candidate files =="
git ls-files | rg '(^|/)main\.py$|cloud-ai/app/main\.py' || true

echo "== file outline/size =="
wc -l cloud-ai/app/main.py
ast-grep outline cloud-ai/app/main.py --view expanded || true

echo "== relevant section =="
sed -n '70,125p' cloud-ai/app/main.py

echo "== redis/lpush occurrences =="
rg -n "TimeoutError|brpop|lpush|continue|retry|dead" cloud-ai/app/main.py

Repository: baasith6/camera-phase-1

Length of output: 3584


🌐 Web query:

Redis Redis-py TimeoutOperationError documentation operation failure retry backoff

💡 Result:

In the redis-py library, there is no exception named TimeoutOperationError. The standard exception for operation timeouts is redis.exceptions.TimeoutError [1][2]. Redis-py includes built-in, configurable support for retrying operations that fail due to transient errors, such as TimeoutError and ConnectionError [3][4]. Retry and Backoff Configuration: You can configure retry behavior by passing a Retry object to your Redis client instance [3][5]. This object allows you to specify a backoff strategy and the maximum number of retry attempts [6][3]. 1. Retry Instance: Defines how many times to retry and which exceptions trigger a retry [3]. 2. Backoff Strategy: Controls the delay between retry attempts. Common strategies include ExponentialBackoff, ExponentialWithJitterBackoff, and ConstantBackoff [7]. Using jitter (e.g., ExponentialWithJitterBackoff) is recommended to prevent thundering herd problems [3][7]. 3. Supported Errors: The Retry instance includes a supported_errors parameter to specify which exceptions should trigger a retry. By default, this typically includes ConnectionError and TimeoutError [6][3]. Example Configuration: Below is an example of how to configure a client with retry logic and exponential backoff: from redis import Redis from redis.retry import Retry from redis.backoff import ExponentialBackoff from redis.exceptions import ConnectionError, TimeoutError # Configure retry: 3 attempts, exponential backoff starting at 1 second, capped at 10 seconds retry_strategy = Retry(ExponentialBackoff(cap=10, base=1), 3) client = Redis( host='localhost', port=6379, retry=retry_strategy, retry_on_error=[ConnectionError, TimeoutError]) Default Behavior: As of recent versions (6.0.0+), redis-py automatically attempts a failed command three times by default using an exponential backoff strategy with jitter if no explicit retry configuration is provided [3]. Important Considerations: - Timeouts: Ensure your socket_timeout and socket_connect_timeout are set to appropriate values. Timeouts that are too short may trigger unnecessary retries for commands that would have succeeded, while excessively long timeouts can cause application threads to hang [3]. - Pipelines: Be aware that historical issues have been reported where retry logic did not behave as expected during pipeline execution [8]. Always verify behavior in your specific environment if using pipelines.

Citations:


Scope the timeout handler to BRPOP only.

The outer except redis.TimeoutError also catches timeouts from p.lpush(...) after a job has been dequeued and processed. In that case continue forgets the current job, so missed retry/dead-lettering can leave work lossy. Catch timeout only around brpop, or persist/requeue the affected job before continuing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cloud-ai/app/main.py` around lines 108 - 110, Restrict the redis.TimeoutError
handling in the worker loop to the BRPOP call only, so timeouts from p.lpush
after processing a dequeued job are not swallowed by the same continue path.
Preserve the existing idle-timeout behavior for BRPOP while ensuring
post-processing failures retain the current job for the established retry or
dead-letter flow.

Comment on lines +40 to +43
$candidates += @(
(Join-Path $user.FullName 'AppData\Local\Programs\Inno Setup 6\ISCC.exe'),
(Join-Path $user.FullName 'AppData\Local\Programs\Inno Setup 6\Compil32.exe')
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | grep -E '(^|/)build\.ps1$|Connector' | head -100

echo "== target =="
if [ -f connector/installer/build.ps1 ]; then
  cat -n connector/installer/build.ps1
else
  fd -a 'build\.ps1$' . | sed -n '1,80p'
fi

echo "== search iscc usage =="
rg -n "Compil32|ISCC|& \$iscc|\.(\$iscc)|Invoke|Start" connector/installer 2>/dev/null || true

Repository: baasith6/camera-phase-1

Length of output: 9382


🌐 Web query:

Inno Setup Compil32.exe ISCC.exe command line compiler GUI compiler

💡 Result:

Inno Setup provides two primary executables for compiling installation scripts: Compil32.exe and ISCC.exe. Both rely on the same core compilation engine (ISCmplr.dll) to generate installers [1]. Compil32.exe Compil32.exe is the GUI-based Integrated Development Environment (IDE) for Inno Setup [1]. It is primarily designed for developers to interactively write, edit, and compile installation scripts (.iss files) [1]. While it can be invoked from the command line using the /cc parameter (e.g., compil32 /cc "script.iss"), it is not intended for headless or silent automation, as it does not suppress the progress display or graphical error messages [2][3]. ISCC.exe ISCC.exe (Inno Setup Command-line Compiler) is a dedicated console-mode application specifically designed for command-line usage [2][4]. It is the recommended tool for build automation, continuous integration pipelines, and any scenario requiring silent or non-interactive compilation [5][4]. Key differences and features: - Usage: Use ISCC.exe for scripts, batch files, and automated build environments [5][4]. Use Compil32.exe for manual script development and editing [1]. - Silent Compilation: ISCC.exe supports quiet mode via the /Q or /Qp flags, allowing you to hide progress displays or suppress output except for error messages [2][4]. - Command-line Options: ISCC.exe accepts various parameters to override script directives at runtime, such as /O (output path), /F (output filename), and /S (SignTool configuration) [2][4]. It also supports extended parameters for the Inno Setup Preprocessor (ISPP) [6]. - Exit Codes: Both compilers return standard exit codes: 0 for success, 1 for invalid parameters/internal errors, and 2 for compilation failure [2][3]. For command-line automation, the standard practice is to use ISCC.exe [5][7]. You can verify available options by running iscc /? in your command prompt [5][4].

Citations:


Do not select Compil32.exe as an ISCC replacement.

The build invokes the selected compiler synchronously (& $iscc $IssFile). Compil32.exe is the GUI IDE and is not suitable for headless automation, so line 42 should be restricted to ISCC.exe.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@connector/installer/build.ps1` around lines 40 - 43, Update the candidate
list in the Inno Setup discovery logic to include only ISCC.exe and remove the
Compil32.exe path from the candidates added for each user. Preserve the existing
Join-Path and synchronous compiler selection flow.

Comment on lines +112 to +118
Write-Host "==> PyInstaller deps..."
& $python -m pip install -q -r (Join-Path $ConnectorRoot "requirements.txt") -r (Join-Path $ConnectorRoot "requirements-build.txt")

Write-Host "==> PyInstaller..."
Push-Location $ConnectorRoot
try {
& python -m PyInstaller --noconfirm --clean --distpath $DistDir --workpath (Join-Path $DistDir "build") $SpecFile
& $python -m PyInstaller --noconfirm --clean --distpath $DistDir --workpath (Join-Path $DistDir "build") $SpecFile

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file exists and relevant lines =="
if [ -f connector/installer/build.ps1 ]; then
  nl -ba connector/installer/build.ps1 | sed -n '90,135p'
else
  echo "connector/installer/build.ps1 not found"
fi

echo
echo "== search for PowerShell exit code handling in same file =="
rg -n 'LASTEXITCODE|exit|pip|PyInstaller|Set-StrictMode|ErrorAction' connector/installer/build.ps1 || true

echo
echo "== package manifest snippets if present =="
git ls-files | rg '(^|/)requirements.*\.txt$|package\.json|pyproject\.toml|Pipfile|poetry\.lock' || true

Repository: baasith6/camera-phase-1

Length of output: 238


🏁 Script executed:

#!/bin/sh
set -euo pipefail

echo "== file metadata =="
test -f connector/installer/build.ps1 && echo "found" || echo "missing"

echo
echo "== relevant lines using awk =="
if [ -f connector/installer/build.ps1 ]; then
  awk 'NR>=100 && NR<=130 { printf "%6d\t%s\n", NR, $0 }' connector/installer/build.ps1
fi

echo
echo "== PowerShell / pip / exit handling references =="
if [ -f connector/installer/build.ps1 ]; then
  grep -nE 'LASTEXITCODE|Set-StrictMode|ExitCode|pip|PyInstaller|try|catch|throw|exit ' connector/installer/build.ps1 || true
fi

echo
echo "== repository shell availability =="
command -v bash || true
command -v awk || true
command -v sed || true
command -v python3 || true
command -v node || true

Repository: baasith6/camera-phase-1

Length of output: 3206


🌐 Web query:

PowerShell & executable native program non-zero exit code does not stop script LASTEXITCODE

💡 Result:

By default, PowerShell does not stop execution when a native (external) executable returns a non-zero exit code [1][2]. This occurs because native programs operate outside of PowerShell's internal error-handling system, which typically relies on exceptions [1][3]. Instead, native programs report success or failure solely through the $LASTEXITCODE automatic variable, where 0 conventionally indicates success and non-zero values indicate failure [1][4][3]. To make your script stop automatically on a non-zero exit code, you have the following primary options: Option 1: Modern PowerShell (7.4+) In PowerShell 7.4 and later, you can enable native error integration by setting the $PSNativeCommandUseErrorActionPreference preference variable to $true [1][3]. When this is active, PowerShell treats non-zero exit codes as non-terminating errors that respect the $ErrorActionPreference variable [1][5]. By setting $ErrorActionPreference = 'Stop', these errors become script-terminating and will halt execution [1][6]. $PSNativeCommandUseErrorActionPreference = $true $ErrorActionPreference = 'Stop' & your-executable.exe Option 2: Explicit Check (Compatible with all versions) For versions older than 7.4, or if you prefer explicit control, you must manually check the exit code immediately after the command runs [2][7]. The most common approach is to verify $LASTEXITCODE or the success status variable $? [4][8]. & your-executable.exe if ($LASTEXITCODE -ne 0) { throw "Command failed with exit code $LASTEXITCODE" } Alternatively, you can use the $? variable, which is set to $true if the last operation succeeded (exit code 0) and $false otherwise [4][3]. & your-executable.exe if (-not $?) { throw "Command failed" } Summary of Key Variables: - $LASTEXITCODE: Stores the numeric exit code of the last native program [1][9]. - $?: A boolean that is true if the last operation (cmdlet or native program) succeeded, and false if it failed [4][3]. - $ErrorActionPreference: Determines how PowerShell reacts to errors; setting it to 'Stop' is critical for terminating execution automatically when using modern native command integration [1][3].

Citations:


🏁 Script executed:

#!/bin/sh
set -euo pipefail

echo "== PowerShell handling at top of build.ps1 =="
awk 'NR>=1 && NR<=90 { printf "%6d\t%s\n", NR, $0 }' connector/installer/build.ps1

echo
echo "== explicit native-command error handling settings in repository =="
grep -rnE 'PSNativeCommandUseErrorActionPreference|ErrorActionPreference|\$Err[A-Za-z]+ErrorActionPreference' . || true

echo
echo "== pip install invocations and immediate status checks in repository =="
grep -rnE '& \$python -m pip install|\$python -m pip install|\$LASTEXITCODE|\$?' connector/installer/build.ps1 || true

Repository: baasith6/camera-phase-1

Length of output: 11928


Fail immediately when dependency installation fails.

The $ErrorActionPreference = "Stop" setting does not affect a non-zero native pip exit code, so the script can continue to PyInstaller with stale or incomplete dependencies. Check $LASTEXITCODE immediately after the pip install command.

Proposed fix
 & $python -m pip install -q -r (Join-Path $ConnectorRoot "requirements.txt") -r (Join-Path $ConnectorRoot "requirements-build.txt")
+if ($LASTEXITCODE -ne 0) {
+    throw "Dependency installation failed (exit $LASTEXITCODE)."
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Write-Host "==> PyInstaller deps..."
& $python -m pip install -q -r (Join-Path $ConnectorRoot "requirements.txt") -r (Join-Path $ConnectorRoot "requirements-build.txt")
Write-Host "==> PyInstaller..."
Push-Location $ConnectorRoot
try {
& python -m PyInstaller --noconfirm --clean --distpath $DistDir --workpath (Join-Path $DistDir "build") $SpecFile
& $python -m PyInstaller --noconfirm --clean --distpath $DistDir --workpath (Join-Path $DistDir "build") $SpecFile
Write-Host "==> PyInstaller deps..."
& $python -m pip install -q -r (Join-Path $ConnectorRoot "requirements.txt") -r (Join-Path $ConnectorRoot "requirements-build.txt")
if ($LASTEXITCODE -ne 0) {
throw "Dependency installation failed (exit $LASTEXITCODE)."
}
Write-Host "==> PyInstaller..."
Push-Location $ConnectorRoot
try {
& $python -m PyInstaller --noconfirm --clean --distpath $DistDir --workpath (Join-Path $DistDir "build") $SpecFile
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@connector/installer/build.ps1` around lines 112 - 118, Update the dependency
installation step before the PyInstaller invocation to check $LASTEXITCODE
immediately after the pip command and stop with a nonzero failure when
installation fails. Keep the existing PyInstaller flow unchanged for successful
dependency installation.

Comment thread Jenkinsfile
Comment on lines +15 to +16
ONEVO_PYTHON = 'C:\\Users\\Abdul Baasith\\AppData\\Local\\Python\\bin\\python.exe'
ONEVO_ISCC = 'C:\\Users\\Abdul Baasith\\AppData\\Local\\Programs\\Inno Setup 6\\ISCC.exe'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Move tool paths out of the pipeline source. agent any can run under a different node or service account, where C:\Users\Abdul Baasith\... does not exist; the current documentation also makes operators edit versioned pipeline code for machine configuration.

  • Jenkinsfile#L15-L16: remove the profile-specific values and obtain ONEVO_PYTHON/ONEVO_ISCC from node-level Jenkins environment configuration.
  • docs/JENKINS_DEPLOY.md#L15-L16: instruct operators to configure both variables on the Jenkins agent/service account, not in Jenkinsfile.
  • docs/JENKINS_DEPLOY.md#L94-L94: include Python-path configuration alongside ISCC troubleshooting.
📍 Affects 2 files
  • Jenkinsfile#L15-L16 (this comment)
  • docs/JENKINS_DEPLOY.md#L15-L16
  • docs/JENKINS_DEPLOY.md#L94-L94
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Jenkinsfile` around lines 15 - 16, Move the profile-specific ONEVO_PYTHON and
ONEVO_ISCC assignments out of Jenkinsfile and rely on node-level Jenkins
environment configuration. In docs/JENKINS_DEPLOY.md lines 15-16, instruct
operators to configure both variables for the Jenkins agent/service account
rather than editing Jenkinsfile; in line 94, include Python-path troubleshooting
alongside ISCC troubleshooting.

Comment thread scripts/deploy-vm.ps1
Comment on lines +86 to +89
$installerArgs = @{ BackendUrl = $BackendUrl; AllowHttp = $true }
if ($PythonPath) { $installerArgs.PythonPath = $PythonPath }
if ($IsccPath) { $installerArgs.IsccPath = $IsccPath }
& (Join-Path $root "scripts\build-installer.ps1") @installerArgs

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Restore HTTPS enforcement for public connector traffic. The deployment always passes -AllowHttp, while the baked fallback is a public http:// URL; installers built through this path therefore accept and use unencrypted backend traffic.

  • scripts/deploy-vm.ps1#L86-L89: make HTTP an explicit opt-in switch rather than always setting AllowHttp = $true; use an HTTPS backend by default.
  • connector/app/baked_config.py#L2-L2: do not commit a public plaintext fallback URL; bake the HTTPS endpoint during the installer build.
📍 Affects 2 files
  • scripts/deploy-vm.ps1#L86-L89 (this comment)
  • connector/app/baked_config.py#L2-L2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/deploy-vm.ps1` around lines 86 - 89, Update scripts/deploy-vm.ps1
lines 86-89 so the installer arguments do not always set AllowHttp to true;
expose HTTP as an explicit opt-in while defaulting BackendUrl to HTTPS. Update
connector/app/baked_config.py line 2 to remove the public plaintext fallback and
bake the HTTPS endpoint during installer builds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant